查看原文
其他

2019 下半年 Flutter 实现的性能优化 | 英雄榜

Flutter 谷歌开发者 2021-08-05

作者 / Yuqian Li & Shams Zakhour


高性能是 Flutter 的关键特性之一。我们希望通过本文着重分享在 2019 年下半年由整个 Flutter 社群实现的性能优化。(虽然 2020 年已经过去大半,但我们认为感谢开发者们做出的贡献虽晚不迟!)


当然,如果您在 2020 年帮助 Flutter 提升性能,您也将出现在未来的英雄榜中。我们希望通过分享这些成就,可以激励更多的开发者贡献能量!


我们尤其鼓励编写性能测试来量化性能上的提升,并防止该性能在未来出现倒退。因此,我们在含有量化结果的性能优化的详细说明中,会特别列出每个做出贡献的开发者。


以下是 2019 年下半年的 Flutter 性能汇总和量化结果分享,您可以在后文中阅读性能提升详细内容和贡献来源。



2019 年第 4 季度 (10 月 - 12 月)


已量化的改进
  • 快速滚动浏览大型图像时,内存占用减少 70%

  • 简单 iOS 动画的 CPU/GPU 占用降低 40%
  • 41% 的光标性能加速
  • 通过修复光栅缓存节流,将列表滚动速度提高 10%
  • 缓存性能数据使得仪表板加载速度提高 37 倍
  • 构建 APK 的速度提高至 2.3 倍
  • Flutter 引擎提交时记录的性能指标增加 103 个
  • 应用大小缩减 20%
  • Dart FFI 性能提升了 108 倍
  • 紧凑代码的性能提升 10% – 15%
  • 通过新的增量序列化器将 flutter 测试速度提高了 2.2 倍
  • 通过向 Dart VM JIT 提供内联提示将内核二进制序列化速度提高 10%
  • 异步繁重代码的性能提升了 30%

其他改进

  • 修复了在 iOS 上使用 PlatformView 时的内存泄漏问题
  • 修复了在 iOS 上播放动画时的内存泄漏问题
  • 修复了许多其它的 iOS 内存泄漏
  • 已开始改造 flutter.dev 上的性能 (Performance) 页面并添加了有关衡量应用大小的操作说明
  • 更正了第一帧等待逻辑和衡量
  • DevTools 添加了完整时间线模式,并支持异步和记录的追踪
  • IntelliJ 插件修复了 120FPS 支持
  • 许多时间线追踪改进



2019 年第 3 季度 (7 月 - 9 月)


已量化的改进

  • 矩形和点变换速度提升了 1.5–5 倍
  • iPhone X/Xs 滚动时丢失的帧数减少 N/2–1
  • 通过并行初始化将引擎启动和关闭时间缩短 15%
  • 着色器预热的启动速度加快 14.57 毫秒,内存使用量减少 8MB
  • 代码大小缩减了 1.02%-8.04%
  • Flutter 在 Fuchsia 上的 FPS 提高多达 2 倍;改进了帧时间安排

已量化的回退修复
  • iOS 上 BackdropFilter 的速度提高 3 倍

其他改进
  • DevTools 支持各种显示刷新速率 (例如 60 FPS、120 FPS 等)
  • 目前 VSCode 插件对项目的扫描是异步扫描,这应该会提升扩展程序激活速度并降低触发 VS Code "扩展导致高 CPU" 警告的几率
  • iPhone Xs 已被添加至 Flutter 设备实验室进行基准测试



详细说明


2019 年第 4 季度已量化的改进
快速滚动浏览大型图像时,内存占用减少 70%
  • PR 14265: 清理 IO 线程 GrContext
    https://github.com/flutter/engine/pull/14265
  • PR 46184: 针对快速滚动大型图像的内存测试
    https://github.com/flutter/flutter/pull/46184
  • 仪表板: fast_scroll_large_images__memory 中位数差值减少了 70% (从 400MB 减少到 120MB)
    https://flutter-dashboard.appspot.com/benchmarks.html
  • Issue 19558: 需要清理 IO 线程 GrContext 内存
    https://github.com/flutter/flutter/issues/19558

贡献者: liyuqian、dnfield、chinmaygarde

  • https://github.com/liyuqian

  • https://github.com/dnfield

  • https://github.com/chinmaygarde


简单 iOS 动画的 CPU/GPU 占用降低 40%
  • PR 14104: 重新设计更简单的条件离屏渲染以实现屏幕读取支持
    https://github.com/flutter/engine/pull/14104
  • PR 13976: 根据需求动态确定是否使用离屏表面
    https://github.com/flutter/engine/pull/13976
  • PR 31865: iPhone 6 上的简单动画大量消耗 (约 20%) CPU/GPU/电量
    https://github.com/flutter/flutter/issues/31865
  • simple_animation_perf_iphonexs 的 cpu_percentage 和 gpu_percentage 减少了 40% (从 23%-CPU-14%-GPU 减少到 13%-CPU-8.5%-GPU)
    https://github.com/flutter/flutter/issues/31865#issuecomment-566268237

贡献者: flarliyuqianhixiechinmaygarde
  • https://github.com/flar
  • http://github.com/liyuqian
  • https://github.com/hixie
  • http://github.com/chinmaygarde

41% 的光标性能加速
  • PR 46720: 传递 _caretPrototype 以防止缓存丢失
    https://github.com/flutter/flutter/pull/46720
  • PR 46720: 第 90 百分位帧的构建时间缩短了 41% (从 6.709 毫秒缩短到 4.756 毫秒)
    https://github.com/flutter/flutter/pull/46720
  • [已修复] Issue 24522: 光标性能低下,每帧的 GPU 时间过长
    https://github.com/flutter/flutter/issues/24522

贡献者: garyqian、liyuqian、justinmc

  • https://github.com/garyqian
  • http://github.com/liyuqian
  • https://github.com/justinmc

通过修复光栅缓存节流,将列表滚动速度提高 10%
  • PR 31865: iPhone 6 上的简单动画大量消耗 (约 20%) CPU/GPU/电量
    https://github.com/flutter/flutter/issues/31865
  • PR 13710: 修复图片光栅缓存节流
    https://github.com/flutter/engine/pull/13710
  • PR 45050: 为照片光栅缓存添加 perf 测试
    https://github.com/flutter/flutter/pull/45050
  • 利用 PR 13710 (修复图片光栅缓存节流) 修复了关键问题 43083: 列表滚动不畅
    https://github.com/flutter/flutter/pull/45050

贡献者: liyuqianchinmaygardeflarcyanglazzsunkun

  • http://github.com/liyuqian
  • http://github.com/chinmaygarde
  • https://github.com/flar
  • https://github.com/cyanglaz
  • https://github.com/zsunkun

缓存基准加载速度提高至 37 倍 (仪表板)
  • PR 494: 缓存 get-benchmark
    https://github.com/flutter/cocoon/pull/494
  • PR 484: /api/public/get-status 提供缓存响应
    https://github.com/flutter/cocoon/pull/484
  • 基准加载速度提高至 37 倍 (从 37 秒缩短至 1 秒)
    https://github.com/flutter/cocoon/pull/494#issue-333227543

贡献者: caseyhillerstvolkertdigiterjonahwilliams

  • https://github.com/caseyhillers
  • https://github.com/tvolkert
  • https://github.com/digiter
  • https://github.com/jonahwilliams

构建 APK 的速度提高至 2.3 倍

  • PR 44534: 通过并发运行 gen_snapshot 提高构建 APK 的性能 (大约 50%)
    https://github.com/flutter/flutter/pull/44534
  • 针对目标平台 android-arm、android-arm64 和 android-x64,将 APK 的发布版本构建速度提高至 2.3 倍 (从 140 秒缩短至 60 秒)
    https://github.com/flutter/flutter/pull/44534#issue-339112036

贡献者: jonahwilliamsblastenzandersoxster

  • https://github.com/jonahwilliams
  • https://github.com/blasten
  • https://github.com/zanderso
  • https://github.com/xster

Flutter 引擎提交时记录的性能指标增加 103 个
  • PR 14556: 运行和收集指标
    https://github.com/flutter/engine/pull/14556
  • 相关 issue: PR 37434: 集中性能指标、提供通用提醒,并改进性能仪表板
    https://github.com/flutter/flutter/issues/37434

贡献者: liyuqian、digiter、keyonghan、godofredoc、cbracken

  • http://github.com/liyuqian
  • https://github.com/digiter
  • https://github.com/keyonghan
  • https://github.com/godofredoc
  • https://github.com/cbracken

应用大小缩减 20%

  • 3% 来自将 PC 偏移 (offset) 从 StackMaps 中移出
    https://github.com/dart-lang/sdk/commit/a2bb7301c5795e6b28089a8dc96e6ab5ca798e22
  • 2.58% 来自进一步压缩之前在 StackMaps 中的信息
    https://github.com/dart-lang/sdk/commit/d77f4913a18ecce8c4be95cbaa4299ff1521dc10
  • 1% 来自尽可能规范化 CompressedStackMaps 负载 (如可能)
    https://github.com/dart-lang/sdk/commit/dc808f3fcbf7e6de7e2b25441ff7ed891362e70a
  • 2% 来自在裸机模式下完全启用指令去重
    https://github.com/dart-lang/sdk/commit/e2faac751e1ef3707730e6e48f4d8f22ecbf35c3
  • 0.3% 来自不为需要参数描述符的函数生成单态序言
    https://github.com/dart-lang/sdk/commit/f6477854cdb0da052be3423a24961feaf5a0d845
  • 1% 来自舍弃冗余的 null 初始化存储
    https://github.com/dart-lang/sdk/commit/46cef9bfddf3cfc05618448d228f0e3377058baf
  • 6% 来自减少指令对齐并移除一些调试陷阱指令
    https://github.com/dart-lang/sdk/commit/8e7ffafbafc8203361111ddcafe0e0fcc372edf8
  • 1.2% 来自在调用存根期间而非每个函数序言中调整 CSP
    https://github.com/dart-lang/sdk/commit/c873220e43af1a1f4675df4108e575465e598578
  • 1% 来自 ARM64: 屏蔽 R22 以保留 NullObject()
    https://github.com/dart-lang/sdk/commit/f8d42542ddd40c06bb71d6fb85d78ed4bbffa785
  • 2.5% 来自全程序常量传播
    https://github.com/dart-lang/sdk/commit/f56b0f690789b6f0e2e5bc1340abf4eba414b7a0
  • 0.77% 来自消除死代码
    https://github.com/dart-lang/sdk/commit/b69596bb1ba81874e4b9d7a577071c67c357ec39

贡献者: mraleph、alexmarkov、rmacnak-google、mkustermann、sstrickl、aartbik

  • https://github.com/mraleph
  • https://github.com/alexmarkov
  • https://github.com/rmacnak-google
  • https://github.com/mkustermann
  • https://github.com/sstrickl
  • https://github.com/aartbik

Dart FFI 性能提升了 108 倍

  • Gerrit 120661: 优化静态已知类型的指针操作
    https://dart-review.googlesource.com/c/sdk/+/120661
  • Gerrit 119645: 索引读取和存储的指针优化
    https://dart-review.googlesource.com/c/sdk/+/119645
  • Gerrit 121580: 允许在 AoT 中内嵌强制优化的函数
    https://dart-review.googlesource.com/c/sdk/+/121580

贡献者: dcharkesmkustermannsjindelalexmarkov

  • https://github.com/dcharkes
  • https://github.com/mkustermann
  • https://github.com/sjindel
  • https://github.com/alexmarkov

紧凑代码的性能提升 10–15%
  • Gerrit 117200: 循环分析和 BCE 改进
    https://dart-review.googlesource.com/c/sdk/+/117200
  • golem armv7 的性能提高了 10–15%,以及 TypedData Bench: Gerrit 117200: 循环分析和 BCE 改进
    https://dart-review.googlesource.com/c/sdk/+/117200

贡献者: aartbikmkustermannmraleph

  • https://github.com/aartbik
  • https://github.com/mkustermann
  • https://github.com/mraleph

通过新的增量序列化器将 flutter 测试速度提高了 2.2 倍

  • Gerrit 121121: 默认启用增量序列化器
    https://dart-review.googlesource.com/c/sdk/+/121121
  • "flutter test" 速度提高了 2.2 倍 (时间从 3:38 缩短至 1:39)

贡献者: jensjoha、alexmarkov

  • https://github.com/jensjoha
  • https://github.com/alexmarkov

通过向 Dart VM JIT 提供内联提示将内核二进制序列化速度提高 10%
  • Gerrit 119540: 向内核序列化中的某些方法添加 VM 友好内联指令
    https://dart-review.googlesource.com/c/sdk/+/119540

贡献者: jensjohajohnniwinther

  • https://github.com/jensjoha
  • https://github.com/johnniwinther

异步繁重代码的性能提升了 30%
  • 添加非紧急异步堆栈帧收集器
    https://dart-review.googlesource.com/c/sdk/+/122644

贡献者: cskau-g、mkustermann、mraleph

  • https://github.com/cskau-g
  • https://github.com/mkustermann
  • https://github.com/mraleph

2019 年第 4 季度其他改进

修复了在 iOS 上使用 PlatformView 时的内存泄漏问题

  • 修复使用 PlatformView [IOS] 时的内存泄漏
    https://github.com/flutter/engine/pull/7919
  • 使用 PlatformView [IOS] 时的内存泄漏
    https://github.com/flutter/flutter/issues/24714

修复了在 iOS 上播放动画时的内存泄漏问题

  • Gerrit 260538: 不为创建无法缓存纹理的生成器分配无效消息
    https://skia-review.googlesource.com/c/skia/+/260538
  • 在 iOS 上播放动画时的内存泄漏
    https://github.com/flutter/flutter/issues/47108

修复了更多 iOS 内存泄漏
  • https://github.com/flutter/engine/pull/14275

  • https://github.com/flutter/engine/pull/14326

  • https://github.com/flutter/flutter/issues/35243


已开始改造 flutter.dev 上的性能 (Performance) 页面并添加了有关衡量应用大小的操作说明

  • PR 3159: 性能
    https://github.com/flutter/website/pull/3159/

更正了第一帧等待逻辑和衡量
  • PR 37192: 重新 "修复追踪和驱动程序中的第一帧逻辑 (#35297)"
    https://github.com/flutter/flutter/pull/37192
  • 修复了 issue 47108: 在 iOS 上播放动画时的内存泄漏
    https://github.com/flutter/flutter/issues/47108

DevTools 添加了完整时间线模式,并支持异步和记录的追踪

  • PR 1241: 添加完整时间线视图
    https://github.com/flutter/devtools/pull/1241

IntelliJ 插件修复了 120FPS 支持

  • PR 4289: 移除硬编码的刷新速率以进行 fps 计算
    https://github.com/flutter/flutter-intellij/pull/4289

更多时间线追踪改进

  • Gerrit 127920: [时间线] 添加对 android 平台追踪中时间线异步事件的支持
    https://dart-review.googlesource.com/c/sdk/+/127920
  • Gerrit 128200: [时间线] 支持适用于 systrace 的 vm 事件
    https://dart-review.googlesource.com/c/sdk/+/128200
  • Gerrit 127921: 使用 systrace 记录时间线事件时支持更多同步事件
    https://dart-review.googlesource.com/c/sdk/+/127921
  • PR 14323: 修复使用 systrace 记录事件时缺少 API 流的问题
    https://github.com/flutter/engine/pull/14323
  • PR 14521: 可以在发布版本模式下启用支持时间线
    https://github.com/flutter/engine/pull/14521
  • PR 14319: 修复 flutter 引擎启动时缺少时间线事件的问题
    https://github.com/flutter/engine/pull/14319
  • PR 47742: 修复时间线摘要时长事件
    https://github.com/flutter/flutter/pull/47742
  • Gerrit 131360: 支持时间线转化为 iOS 平台追踪
    https://dart-review.googlesource.com/c/sdk/+/131360
  • PR 16520: 支持无限追踪缓冲
    https://github.com/flutter/engine/pull/16520
  • PR 47419: 支持无限时间线记录器
    https://github.com/flutter/flutter/pull/47419

2019 年第 3 季度已量化的改进
矩形和点变换速度提升了 1.5–5 倍
  • PR 37275: 优化 matrix_utils 中的 transformRect 和 transformPoint 方法
    https://github.com/flutter/flutter/pull/37275
  • MatrixUtils_affine_transformRect_iteration 速度提升至 5.3 倍 (从 2,300 毫秒缩短至 430 毫秒)
  • MatrixUtils_affine_transformPoint_iteration 速度提升至 1.5 倍 (从 466 毫秒缩短至 320 毫秒)

贡献者: flar、yjbanov、dnfield

  • https://github.com/flar
  • https://github.com/yjbanov
  • https://github.com/dnfield

iPhone X/Xs 滚动时丢失的帧数减少 N/2–1
  • https://github.com/flutter/engine/pull/12385

  • PR 12385: 再处理 "iOS 不规则输入事件交付"
    https://github.com/flutter/engine/pull/12385
  • 将滚动 N 个帧时丢失帧的数量 (最糟糕情况) 从 N/2 减少至 1。实机测试中,在修复之前平均丢失的帧数量为 N/10 个。
  • 修复了以下得票数最多的 issue 之一:
    Issue 31086: 由于不规则输入事件交付,iPhone X、Xs 设备上的滚动性能严重下降
    https://github.com/flutter/flutter/issues/31086

贡献者: liyuqian、chinmaygarde、gaaclarke

  • http://github.com/liyuqian

  • http://github.com/chinmaygarde

  • https://github.com/gaaclarke


通过并行初始化将引擎启动和关闭时间缩短 15%

  • PR 10182: 通过允许对初始化进行并行处理加快了 flutter 启动速度

    https://github.com/flutter/engine/pull/10182

  • BM_ShellInitializationAndShutdown 的速度提升至 1.16 倍 (从 3,829,377 纳秒缩短至 3,286,713 纳秒)

    https://github.com/flutter/engine/pull/10182#issuecomment-531953100


贡献者: gaaclarkechinmaygardeliyuqian

  • https://github.com/gaaclarke
  • http://github.com/chinmaygarde
  • http://github.com/liyuqian

着色器预热的启动速度加快 14.57 毫秒,内存使用量减少 8MB
  • PR 36482: 通过仅在 100x100 表面上绘制加快了着色器预热速度
    https://github.com/flutter/flutter/pull/36482
  • 启动时读取/转换像素的时间节省了 14.57 毫秒 (从 18.848 毫秒缩短至 4.279 毫秒)
    https://github.com/flutter/flutter/pull/36482#issue-299068276
  • 启动内存中位数节省了 8MB (从 39,220KB 减少到 31,184KB)
    https://github.com/flutter/flutter/pull/36482#issuecomment-531067365
  • 结束内存中位数节省了 4MB (从 45,034KB 减少到 40,980KB)
    https://github.com/flutter/flutter/pull/36482#issuecomment-531067365

贡献者: gaaclarkeliyuqiandnfield

  • https://github.com/gaaclarke
  • http://github.com/liyuqian
  • https://github.com/dnfield

代码大小缩减了 1.02%-8.04%
  • https://dart-review.googlesource.com/c/sdk/+/118280

  • https://dart-review.googlesource.com/c/sdk/+/112758

  • https://dart-review.googlesource.com/c/sdk/+/118181

  • armv8 animation_bench_instructions_size 减小 8.04% (从 5.57MB 缩减至 5.13MB)
  • armv7 flutter_gallery_readonlydata_size 减小 2.7% (从 2.10MB 减少至 2.05MB)
  • armv7 layout_bench_instructions_size 减小 1.22% (从 2.10MB 减少至 2.05MB)

贡献者: johnniwintheraartbikrmacnak-googlejensjohaalexmarkovmkustermann

  • https://github.com/johnniwinther
  • https://github.com/aartbik
  • https://github.com/rmacnak-google
  • https://github.com/jensjoha
  • https://github.com/alexmarkov
  • https://github.com/mkustermann

Flutter 在 Fuchsia 上的 FPS 提高多达 2 倍;改进了帧时间安排

  • https://fuchsia-review.googlesource.com/c/topaz/+/280230

  • https://fuchsia-review.googlesource.com/c/topaz/+/286735

  • https://fuchsia-review.googlesource.com/c/topaz/+/300135

  • https://fuchsia-review.googlesource.com/c/topaz/+/306773

  • https://fuchsia-review.googlesource.com/c/topaz/+/306772

  • https://fuchsia-review.googlesource.com/c/topaz/+/307953


贡献者: drevemanamottrosswangmikejurka

  • https://github.com/dreveman
  • https://github.com/amott
  • https://github.com/rosswang
  • https://github.com/mikejurka

2019 年第 3 季度已量化的回退修复
iOS 上 BackdropFilter 的速度提高 3 倍
  • https://skia-review.googlesource.com/c/skia/+/237904

  • https://skia-review.googlesource.com/c/skia/+/234413

  • https://github.com/flutter/flutter/pull/38814

  • GM_savelayer_with_backdrop 的速度加快了 3 倍 (从 110 毫秒缩短至 34 毫秒)

    https://perf.skia.org/e/?begin=1567010155&end=1567104574&queries=name%3DGM_savelayer_with_backdrop%26os%3DiOS

  • 修复了回退 
    https://github.com/flutter/flutter/issues/36064

贡献者: lhkbobliyuqianflar

  • https://github.com/lhkbob
  • http://github.com/liyuqian
  • https://github.com/flar

之所以能够实现这些大幅度的改进 (例如提升至 3 倍之多),除去 2019 年的努力外,老版本不尽如人意的表现可能也有所 "贡献"。我们也在此分享一些同样重大的性能回退问题的修复结果。我们对这些努力深表感激,如果没有这些工作,我们会继续面临性能不佳乃至回退的问题。当然,我们也不希望大幅度的改进令较小的提升相形见绌: 有时候性能的小幅度提升仅仅只是因为起点太高,这本是好事。


2019 年第 3 季度其他改进
  • DevTools 支持各种显示刷新速率 (例如 60 FPS、120 FPS 等)
    https://github.com/flutter/devtools/blob/master/packages/devtools/CHANGELOG.md#018---2019-10-01
  • 目前 VSCode 插件对项目的扫描是异步扫描,这应该会提升扩展程序激活速度并降低触发 VS Code "扩展导致高 CPU" 警告的几率。(#1840/#2003/#1961)
    https://github.com/Dart-Code/Dart-Code/issues/1840
    https://github.com/Dart-Code/Dart-Code/issues/2003
    https://github.com/Dart-Code/Dart-Code/issues/1961
  • iPhone Xs 已被添加至 Flutter 设备实验室进行基准测试
    https://github.com/flutter/flutter/issues/34590



结论


△ 53% 的受访者对 Flutter 表示非常满意

总体则有 92% 的受访者表示满意

得益于这些贡献,Flutter 移动端性能的满意度从 2019 年第三季度的 85% 上升到 2020 年的 92%。本文虽已尽力列出大家的贡献,但仍然可能遗漏 2019 年第 3 到第 4 季度的一些贡献。如果有任何遗漏的贡献,请随时告诉我们,我们会将其纳入下一次更新。


Flutter 2020 年第三季度调研已经开启,本次调研会重点涉及移动端和 Web 端的体验细节,以及询问您对一些动画效果的看法。扫描二维码进入调研,请注意本次调研将于 2020 年 8 月 27 日截止

对于 Flutter 性能优化,您还有什么想法和建议吗?一起在文末微信留言区交流起来!


推荐阅读






 点击屏末 | 阅读原文 | 访问 Flutter 开发者社区中文资源



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存